package com.tinem.platform.service.task.service;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Data
@Slf4j
public class ElasticsearchClient {

    RestHighLevelClient client;

    public ElasticsearchClient(String host, int port, String scheme, boolean auth, String authUserName, String authPassword) {
        HttpHost httpHost = new HttpHost(host, port, scheme);
        RestClientBuilder restClientBuilder = RestClient.builder(httpHost).setRequestConfigCallback(builder->{
            builder.setConnectTimeout(-1);
            builder.setSocketTimeout(-1);
            builder.setConnectionRequestTimeout(-1);
            return builder;
        }).setHttpClientConfigCallback(builder->{
            if(auth){
                CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(authUserName, authPassword));
                builder.disableAuthCaching();
                return builder.setDefaultCredentialsProvider(credentialsProvider);
            }else{
                return builder;
            }
        });
        client = new RestHighLevelClient(restClientBuilder);
    }

    /**
     * 判断索引是否存在
     * @param indexName
     * @return
     * @throws IOException
     */
    public boolean isIndex(String indexName) throws IOException {
        GetIndexRequest request = new GetIndexRequest();
        return client.indices().exists(request.indices(indexName), RequestOptions.DEFAULT);
    }
    /**
     * 获取索引按照日期排序的最后一条记录
     * @param indexName
     * @return
     * @throws IOException
     */
    public boolean getTopByDate(String indexName, String dateFieldName) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(0);
        sourceBuilder.size(1);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        sourceBuilder.sort(new FieldSortBuilder(dateFieldName).order(SortOrder.ASC));
        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        //4、处理响应
        //搜索结果状态信息
        RestStatus status = searchResponse.status();
        TimeValue took = searchResponse.getTook();
        Boolean terminatedEarly = searchResponse.isTerminatedEarly();
        boolean timedOut = searchResponse.isTimedOut();

        //分片搜索情况
        int totalShards = searchResponse.getTotalShards();
        int successfulShards = searchResponse.getSuccessfulShards();
        int failedShards = searchResponse.getFailedShards();

        //处理搜索命中文档结果
        SearchHits hits = searchResponse.getHits();

        TotalHits totalHits = hits.getTotalHits();
        float maxScore = hits.getMaxScore();

        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit

            String index = hit.getIndex();
            String type = hit.getType();
            String id = hit.getId();
            float score = hit.getScore();

            //取_source字段值
            String sourceAsString = hit.getSourceAsString(); //取成json串
            Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 取成map对象
            log.info("index:" + index + "  type:" + type + "  id:" + id);
            log.info(sourceAsString);
        }
        return false;
    }
}
